package com.jianggujin.dbfly.mybatis.xmltag;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;

import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.jianggujin.dbfly.mybatis.JXMLMapperEntityResolver;
import com.jianggujin.dbfly.mybatis.JXMLScriptBuilder;
import com.jianggujin.dbfly.mybatis.util.JMybatisUtils;
import com.jianggujin.dbfly.mybatis.util.JNodeUtils;
import com.jianggujin.dbfly.mybatis.util.JProviderHelper;
import com.jianggujin.dbfly.util.JDBFlyException;
import com.jianggujin.dbfly.util.JStringUtils;
import com.jianggujin.dbfly.util.dtd.JDTD;
import com.jianggujin.dbfly.util.dtd.JDTDAttribute;
import com.jianggujin.dbfly.util.dtd.JDTDElement;
import com.jianggujin.dbfly.util.dtd.JDTDEmpty;
import com.jianggujin.dbfly.util.dtd.JDTDItem;
import com.jianggujin.dbfly.util.dtd.JDTDMixed;

/**
 * 条件节点处理器
 * 
 * @author jianggujin
 *
 */
public class JConditionHandler implements JNodeHandler {

    @Override
    public void handleNode(JXMLScriptBuilder builder, XNode nodeToHandle, List<SqlNode> targetContents) {
        try {
            Document document = JMybatisUtils.newDocument();
            Element mapperElement = document.createElement("mapper");
            Element sqlElement = document.createElement("sql");
            sqlElement.setAttribute("id", "sql" + System.currentTimeMillis());
            JProviderHelper.conditionWhereClause(document, sqlElement,
                    JNodeUtils.getRequiredAttribute(nodeToHandle, "name"));
            mapperElement.appendChild(sqlElement);
            document.appendChild(mapperElement);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            JMybatisUtils.transform(document, stream);
            XPathParser parser = new XPathParser(new ByteArrayInputStream(stream.toByteArray()), true,
                    builder.getConfiguration().getVariables(), new JXMLMapperEntityResolver());
            nodeToHandle = parser.evalNode("/mapper/sql");
            targetContents.add(builder.parseDynamicTags(nodeToHandle));
        } catch (Exception e) {
            throw new JDBFlyException(JStringUtils.format("{}节点解析失败", nodeToHandle.getName()), e);
        }
    }

    @Override
    public void accept(JDTD dtd) {
        JDTDItem empty = new JDTDEmpty();
        dtd.add(new JDTDElement("condition", empty, new JDTDAttribute("name")));

        for (String name : MYBATIS_INNER_ELEMENTS) {
            JDTDElement element = dtd.get(name);
            JDTDMixed mixed = (JDTDMixed) element.getContent();
            mixed.add("condition");
        }
    }
}
